/* ez_net.c -- Basic TCP socket stuff made a bit less boring
 *
 * Copyright (c) 2006-2012, Salvatore Sanfilippo <antirez at gmail dot com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of Redis nor the names of its contributors may be used
 *     to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef EZ_NET_H
#define EZ_NET_H

#define ANET_OK      0
#define ANET_ERR     -1
#define ANET_EAGAIN  -10

/* create server */
int ez_net_tcp_server(int port, char *bindaddr, int backlog);
int ez_net_tcp6_server(int port, char *bindaddr, int backlog);

/* 标准的accept模式 */
int ez_net_tcp_accept2(int fd, char *ip, size_t ip_len, int *port);
#define ez_net_tcp_accept(fd)                   (ez_net_tcp_accept2(fd, NULL, 0, NULL))

int ez_net_close_socket(int s);

/* create client */
int ez_net_tcp_connect(const char *addr, int port);
int ez_net_tcp_connect_non_block(const char *addr, int port);

/* NonBlock read write
   @return ANET_EAGAIN:(非阻塞模式)读写已经执行, 读写字节数在nbytes
   @return ANET_ERR   :读写错误
   @return ANET_OK    :读写成功
 */
int ez_net_read(int fd, char *buf, size_t bufsize, ssize_t *nbytes);
int ez_net_write(int fd, char *buf, size_t bufsize, ssize_t *nbytes);

/* socket option */
int ez_net_set_send_buf_size(int fd, int buffsize);

int ez_net_set_non_block(int fd);
int ez_net_set_reuse_addr(int fd);

int ez_net_set_tcp_nodelay(int fd, int val);
#define ez_net_tcp_enable_nodelay(fd)          (ez_net_set_tcp_nodelay(fd, 1))
#define ez_net_tcp_disable_nodelay(fd)         (ez_net_set_tcp_nodelay(fd, 0))

int ez_net_tcp_keepalive(int fd, int interval);
int ez_net_set_ipv6_only(int fd);

/* get socket's ip port info */
int ez_net_peer_name(int fd, char *ip, size_t ip_len, int *port);
int ez_net_socket_name(int fd, char *ip, size_t ip_len, int *port);

int ez_net_resolve_host_name(char *host, char *ipbuf, size_t ipbuf_len);
int ez_net_resolve_host_ip(char *host, char *ipbuf, size_t ipbuf_len);
#endif				/* EZ_NET_H */
